class Vector(list):
    def __iadd__(self, vector):
        return Vector((self[i] + vector[i] for i in xrange(3)))

    def __imul__(self, amount):
        return Vector((component * amount for component in self))

    def __mul__(self, amount):
        return Vector((component * amount for component in self))

    def __sub__(self, vector):
        return Vector((self[i] - vector[i] for i in xrange(3)))

    def dot_product(self, vector):
        return self[0] * vector[0] + self[1] * vector[1] + self[2] * vector[2]

    def magnitude_squared(self):
        return self[0]**2 + self[1]**2 + self[2]**2

    def magnitude(self):
        return math.sqrt(self.magnitude_squared())

    def normalise(self):
        mag = self.magnitude()
        self[0] /= mag
        self[1] /= mag
        self[2] /= mag

class Line(object):
    def __init__(self, position, direction):
        self.pos = Vector(position)
        self.dir = Vector(direction)

def check_point(start_pos, direction, point):
    rhos = [point[i] - start_pos[i] for i in range(3)]
    while 1:
        try:
            rhos.remove(0)
        except ValueError:
            break
    if rhos:
        check = rhos[0]
        for rho in rhos:
            if rho != check:
                return False
    return True

def check_cross(line1, line2):
    # |pos[0]|     |dir[0]| = |pos[0]| +  |dir[0]|
    # |pos[1]| + mu|dir[1]| = |pos[1]| + j|dir[1]|
    # |pos[2]|     |dir[2]| = |pos[2]| +  |dir[2]|
    if line1.dir == line2.dir:
        if line1.pos == line2.pos:
            return "Same path"
        else:
            return "Parallel, no death today"
    try:
        muinj = (line2.pos[0] + complex(0, line2.dir[0]) - line1.pos[0])/line1.dir[0]
    except ZeroDivisionError:
        muinj = line2.pos[0] + complex(0, line2.dir[0]) - line1.pos[0]
        #muinj = 0
        #raise ZeroDivisionError
    # mu = (2pos[0] + 2dir[0]j - 1pos[0])/1dir[0]
    print "muinj", muinj
    j = (line2.pos[1] + complex(0, line2.dir[1]) - line1.pos[1] - line1.dir[1]*muinj)
    print 'j1', j
    try:
        j = j.real/j.imag
    except ZeroDivisionError:
        print "skew"
        j = 0
    mu = muinj.real + muinj.imag * j
    print 'mu = %f, j = %f' % (mu, j)
    print [(line1.pos[i] + mu * line1.dir[i], line2.pos[i] + j * line2.dir[i]) for i in range(3)]
    if line1.pos[2] + mu * line1.dir[2] == line2.pos[2] + j * line2.dir[2]:
        return "They cross!"
    else:
        return "No death today"

if __name__ == "__main__":
    start = (1, 1.2, 0)
    dir = (0, 1, 1)
    point = (1, 4.2, 3)
    print check_cross(Line((12,4,8), (6,2,9)), Line((3,7,2),(9,5,8)))
    print check_cross(Line((0,0,0), (-1,1,1)), Line((1,1,0),(-1,1,0)))
    #import timeit
    #t = timeit.Timer("check_point((1,1.2,0),(0,1,1),(1,4.2,3))",
    #                 "from __main__ import check_point")
    #length = t.timeit(100000)
    #print "%f secs, %f per 10th sec" % (length, 100000/(length*10))